using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Diagnostics;
using System.ComponentModel;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;
using THSLib;
using THSERP.BusinessEntities;
namespace THSERP.BaseProvider
{
    public class THSItemsEntityList<T> : THSList<T>
        where T : ERPModuleItemsEntity, new()
    {
        #region Invalidate
        public override void Invalidate(DataSet ds)
        {
            BaseBusinessController objItemController = BusinessControllerFactory.GetBusinessController(ItemTableName + "Controller");
            this.Clear();

            if (ds.Tables.Count > 0)
            {
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    BusinessObject objItemInfo = (BusinessObject)objItemController.GetObjectFromDataRow(row);
                    T objT = new T();
                    (objT as ERPModuleItemsEntity).GetFromBusinessObject(objItemInfo);
                    this.Add(objT);
                }
            }

            //Invalidate original list same as itself
            OriginalList.Clear();
            foreach (T obj in this)
                OriginalList.Add((T)obj.Clone());

            
            if (GridControl != null)
            {
                GridControl.RefreshDataSource();
                if (this.Count > 0)
                {
                    GridViewFocusRow(0);
                }
                else
                {
                    Entity.InvalidateModuleObject(BusinessObjectFactory.GetBusinessObject(ItemTableName + "Info"));
                }
            }
        }

        public virtual void InvalidateAndNotUpdateModuleObjects(int iObjectID)
        {
           
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(Entity.MainObject);
            BaseBusinessController objItemController = BusinessControllerFactory.GetBusinessController(ItemTableName + "Controller");
            DataSet ds = new DataSet();

            if (Relation.Equals(cstRelationForeign))
            {
                ds = objItemController.GetAllDataByForeignColumn(ItemTableForeignKey, iObjectID);

            }
            else if (Relation.Equals(cstRelationParent))
            {
                ds = objItemController.GetAllObjectsByObjectParentID(iObjectID);
            }

            this.Clear();

            if (ds.Tables.Count > 0)
            {
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    BusinessObject objItemInfo = (BusinessObject)objItemController.GetObjectFromDataRow(row);
                    T objT = new T();
                    (objT as ERPModuleItemsEntity).GetFromBusinessObject(objItemInfo);
                    this.Add(objT);
                }
            }
        }
        
        #endregion

        #region Save List
        public override T SaveObjectToList(bool IsNew)
        { 
            //Invalidate look up edit columns
            if (GridControl != null)
                GridControl.InvalidateLookupEditColumns();

           
            T objT = new T();

            (objT as ERPModuleItemsEntity).GetFromBusinessObject(Entity.ModuleObjects[ItemTableName]);

            if (IsNew)
            {
                String strPrimaryKey = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ID";
                THSDbUtil.SetPropertyValue(objT, strPrimaryKey, 0);
                this.Add(objT);
            }
            else
            {
                if (CurrentIndex >= 0)
                    this[CurrentIndex] = objT;
            }
            return objT;
        }
        #endregion

        #region GridControl,GridView event handlers
        protected override void GridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            DevExpress.XtraGrid.Views.Grid.GridView gridView = (DevExpress.XtraGrid.Views.Grid.GridView)GridControl.Views[0];
            if (this.Count > 0)
                if (CurrentIndex >= 0)
                {
                    String strMainTableName = String.Empty;
                    if (Entity.MainObject != null)
                        strMainTableName = THSUtil.GetTableNameFromBusinessObject(Entity.MainObject);

                    if (ItemTableName.Equals(strMainTableName))
                    {
                        Entity.MainObject = (BusinessObject)this[CurrentIndex].Clone();
                        Entity.UpdateMainObjectBindingSource();
                    }
                    else
                        Entity.InvalidateModuleObject((T)this[CurrentIndex].Clone(), ItemTableName);
                }

        }

        public override void GridViewFocusRow(int iRowHandle)
        {
            GridView.FocusedRowHandle = iRowHandle;
            if (CurrentIndex >= 0)
                Entity.InvalidateModuleObject((T)this[CurrentIndex].Clone(), ItemTableName);
        }
        #endregion

        #region Save List, Delete List to database
        public override void SaveItemObjects()
        {
            try
            {
                EndCurrentEdit();

               
                String strItemTablePrimaryKey = THSDbUtil.GetTablePrimaryColumn(ItemTableName);
                BaseBusinessController objItemsController = BusinessControllerFactory.GetBusinessController(ItemTableName + "Controller");

                foreach (T objT in this)
                {
                    BusinessObject obj = objT.SetToBusinessObject(ItemTableName);
                    int iItemObjectID = (int)THSDbUtil.GetPropertyValue(obj, strItemTablePrimaryKey);
                    switch (Relation)
                    {
                        case cstRelationSwitcher:
                            {
                                break;
                            }
                        case cstRelationForeign:
                            {
                                int iParentObjectID = GetParentObjectID();
                                if (iParentObjectID > 0)
                                {
                                    if (THSDbUtil.GetPropertyValue(obj, ItemTableForeignKey) != null)
                                        THSDbUtil.SetPropertyValue(obj, ItemTableForeignKey, iParentObjectID);
                                }
                                break;
                            }
                        case cstRelationParent:
                            {
                                break;
                            }
                        case cstRelationNone:
                            {
                                break;
                            }
                    }

                    //Create or update items
                    if (iItemObjectID > 0)
                    {
                        THSDbUtil.SetPropertyValue(obj, ERPModuleEntities.AAUpdatedUser, THSApp.CurrentUser);
                        THSDbUtil.SetPropertyValue(obj, ERPModuleEntities.AAUpdatedDate, DateTime.Now);
                        objItemsController.UpdateObject(obj);
                    }
                    else
                    {
                        THSDbUtil.SetPropertyValue(obj, ERPModuleEntities.AACreatedUser, THSApp.CurrentUser);
                        THSDbUtil.SetPropertyValue(obj, ERPModuleEntities.AACreatedDate, DateTime.Now);
                        objItemsController.CreateObject(obj);
                    }
                    Entity.SaveObjectItemRelations(objT);
                }

                //Delete items
                foreach (T objT in OriginalList)
                {
                    int iItemObjectID = (int)THSDbUtil.GetPropertyValue(objT, strItemTablePrimaryKey);
                    if (iItemObjectID > 0 && !this.Exists(strItemTablePrimaryKey, iItemObjectID))
                    {
                        objItemsController.DeleteObject(iItemObjectID);
                        Entity.DeleteObjectRelations(ItemTableName, iItemObjectID);
                    }
                }
                //Invalidate original list
                OriginalList.Clear();
                foreach (T objT in this)
                    OriginalList.Add((T)objT.Clone());
            }
            catch (Exception e)
            {
                MessageBox.Show("THSList.SaveItemObjects -" + e.Message, "Bug");
            }
        }
        #endregion

        #region Set Values After Validate Product
        public void SetDefaultValuesFromProduct(int iICProductID)
        {
            if (Entity.ModuleObjects[ItemTableName] != null)
            {
               
                ICProductsController objICProductsController = new ICProductsController();
                ICProductsInfo objICProductsInfo = (ICProductsInfo)objICProductsController.GetObjectByID(iICProductID);

                String strColumnName = String.Empty;

                if (objICProductsInfo != null)
                {
                    //Set Product Name
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductName";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductName);

                    // Set Product Description
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductDesc";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductDesc);

                    //Set Product Type
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ICProductTypeCombo";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductTypeCombo);

                    //Set Product Unit Cost
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductUnitCost";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductSupplierPrice);

                    //Set Product Sell Unit
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductSellUnit";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductSellUnit);

                    //Set Product Basic Unit
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductBasicUnit";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductBasicUnit);

                    //Set Product Packaging Unit
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductPackagingUnit";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductPackUnit);

                    //Set Product Sell Factor
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductSellFactor";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductBasicToSell);

                    //Set Product Packaging Factor
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductPackagingFactor";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductPackToBasic);

                    //Set Product Packaging Factor
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductPicture";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, objICProductsInfo.ICProductPicture);

                    //Set Product Stock and Slot
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], "FK_ICStockID", objICProductsInfo.FK_ICStockID);
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], "FK_ICStockSlotID", objICProductsInfo.FK_ICStockSlotID);

                    //Set Product Default Tax Percent   
                    double dbTaxPercent = Entity.SetDefaultProductTaxPercent(objICProductsInfo);
                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductTaxPercent";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, dbTaxPercent);

                    strColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductQty";
                    THSDbUtil.SetPropertyValue(Entity.ModuleObjects[ItemTableName], strColumnName, 1);

                    Entity.SetValuesAfterValidateProductQty();
                }
            }
        }
        
        #endregion

        #region Update Inventory
        public void UpdateInventory(String strUpdateStatus)
        {
            foreach (T entItems in this)
            {                
                Entity.UpdateInventory((ERPModuleItemsEntity)entItems, strUpdateStatus);
            }
        }        

        #endregion
        
        /// <summary>
        /// Check whether all items of list satisfy inventory conditions.
        /// If exists any invalid item, show status sub screen to confirm user.
        /// </summary>
        /// <remarks></remarks>
        public virtual bool IsInvalidInventory(String transactionType)
        {
            //If items are same, just check one item of which the quantity 
            //is equal to the sum of quantity of identical ones
           
            THSItemsEntityList<T> lstCopy = new THSItemsEntityList<T>();
            foreach (T entItem in this)
                lstCopy.Add((T)entItem.Clone());
            String serialNoColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductSerialNo";
            String qtyColumnName = ItemTableName.Substring(0, ItemTableName.Length - 1) + "ProductQty";
            for (int i = 0; i < lstCopy.Count; i++)
                for (int j = i + 1; j < lstCopy.Count; j++)
                {
                    String serialNo1 = THSDbUtil.GetPropertyValue(lstCopy[i], serialNoColumnName).ToString();
                    String serialNo2 = THSDbUtil.GetPropertyValue(lstCopy[j], serialNoColumnName).ToString();
                    if (serialNo1 == serialNo2)
                    {
                        double qty1 = Convert.ToDouble(THSDbUtil.GetPropertyValue(lstCopy[j], qtyColumnName));
                        double qty2 = Convert.ToDouble(THSDbUtil.GetPropertyValue(lstCopy[j], qtyColumnName));
                        THSDbUtil.SetPropertyValue(lstCopy[i], qtyColumnName, qty1 + qty2);
                        lstCopy.RemoveAt(j);
                        j--;
                    }
                }

            guiInventoryStatus guiInventoryStatus = new guiInventoryStatus();
            foreach (ERPModuleItemsEntity entItem in lstCopy)
            {
                BusinessObject obj = entItem.SetToBusinessObject(ItemTableName);
                String tableName = THSUtil.GetTableNameFromBusinessObject(obj);
                TransactionUtil.InventoryStatus status = Entity.GetInventoryStatus(obj, tableName, transactionType);
                if (status == TransactionUtil.InventoryStatus.Empty)
                    guiInventoryStatus.AddNewRow(obj, tableName, status);
            }
            if (guiInventoryStatus.StatusTable.Rows.Count > 0)
            {
                guiInventoryStatus.ShowDialog();
                return true;
            }
            return false;
        }
    }
}
